/*
 * tcs_tcp_server.c
 *
 *  Created on: 2015-6-8
 *      Author: Xidian
 */



#include "tcp_server.h"
#include "handshake.h"
#include "aes.h"

UINT32 currentLength = 0;
KEYNODE key[SERVER_MAX_CONNECTIONS];


static void
_print_key(const char* name, const DH_KEY key) {
	int i;

	printf("%s=\t", name);
	for (i = DH_KEY_LENGTH-1; i>=0; i--) {
		printf("%02x", key[i]);
	}
	printf("\n");
}


extern uint8_t *fromhex(const char *str);
extern char *tohex(const uint8_t *bin, size_t l);

void server(){
	int tid;

	tid = taskSpawn("tcs_tcp_server", 100, 0,
				2000, (FUNCPTR) tcs_tcp_server, 0, 0, 0, 0,
				0, 0, 0, 0, 0, 0);
	
	if (tid == 0) {
		printf("spawn error\n");
	}
}

void tcs_tcp_server() {

	

	struct sockaddr_in serverAddr;
	struct sockaddr_in clientAddr;
	int sockAddrSize;
	int sFd, newFd;
	char* ip = LOCAL_HOST;

	sockAddrSize = sizeof(struct sockaddr_in);
	bzero((char *) &serverAddr, sockAddrSize);
	serverAddr.sin_family = AF_INET;
	serverAddr.sin_len = (u_char) sockAddrSize;
	serverAddr.sin_port = htons (SERVER_PORT_NUM);
	
	serverAddr.sin_addr.s_addr = inet_addr(ip);

	if ((sFd = socket(AF_INET, SOCK_STREAM, 0)) == ERROR) {
		printf("socket error\n");
		return;
	}
	

	if (bind(sFd, (struct sockaddr *) &serverAddr, sockAddrSize) == ERROR) {
		printf("bind error\n");
		shutdown(sFd, 0);
		return;

	}

	if (listen(sFd, SERVER_MAX_CONNECTIONS) == ERROR) {
		printf("listen error\n");
		shutdown(sFd, 0);
		return;
	}

	while (1) {
		if ((newFd = accept(sFd, (struct sockaddr *) &clientAddr, &sockAddrSize))
			== ERROR) {
			printf("accept error\n");
			shutdown(sFd, 0);
			return;
		}	
		tcs_tcp_msg_deal(newFd, inet_ntoa(clientAddr.sin_addr));
	}
}

void tcs_tcp_msg_deal(int sFd, char * ip) {
	char* server_msg;
	char client_msg[20];
	
	MSG_HandShake msg_HandShake;
	UINT32 client_nonce, server_nonce;
	DH_KEY server_private, server_public, server_secret, client_public;
	aes_encrypt_ctx ctxe;
	uint8_t ibuf[16], obuf[16];
	unsigned char nonce[16];
	KEYNODE keyNode;
		
	//RECV HELLO_MSG
	if (recv(sFd, (char *)&msg_HandShake, sizeof(MSG_HandShake), 0) < 0) {
		printf("\t\t tcs_tcp_msg_recv error!\n");
		shutdown(sFd, 0);
		return;
	}
	printf ("server RECV HAND01\n");
	if (msg_HandShake.type != HAND01){
		shutdown(sFd, 0);
		return;
	}
	server_nonce = random();
	msg_HandShake.type = HAND02;
	msg_HandShake.server_nonce = server_nonce;
	DH_generate_key_pair(server_public, server_private);
	memcpy(&(msg_HandShake.publicKey), &server_public, sizeof(server_public));
	_print_key("server: server_public", server_public);
	_print_key("server: server_private", server_private);
	printf ("server: server_nonce %d\n", server_nonce);
	

	//SEND Public_key_1||nonce_1
	if (send(sFd, (char *)&msg_HandShake, sizeof(MSG_HandShake), 0) == ERROR) {
		shutdown(sFd,0);
		return;
	}
	printf ("server SEND HAND02\n");
	
	//RECV Public_key_2||nonce_1||nonce_2
	if (recv(sFd, (char *)&msg_HandShake, sizeof(MSG_HandShake), 0) < 0) {
		printf("\t\t tcs_tcp_msg_recv error!\n");
		shutdown(sFd, 0);
		return;
	}
	if (msg_HandShake.type != HAND03){
		shutdown(sFd,0);
		return;
	}
	printf ("server RECV HAND03\n");
	memcpy(&client_public, &(msg_HandShake.publicKey), sizeof(msg_HandShake.publicKey));
	client_nonce = msg_HandShake.client_nonce;
	
	if (server_nonce != msg_HandShake.server_nonce){
		shutdown(sFd,0);
		return;
	}
	printf ("server recv: client_nonce %d\n", client_nonce);
	
	DH_generate_key_secret(server_secret, server_private, client_public);
	_print_key("server secret: ", server_secret);
	
	sprintf(nonce,"%x", client_nonce);

	aes_encrypt_key128(fromhex(server_secret), &ctxe);
	memcpy(ibuf, fromhex(nonce), 16);
	aes_ecb_encrypt(ibuf, obuf, 16, &ctxe);
	printf ("server obuf: %s\n", tohex(obuf, 16));
	printf ("this client_nonce is %d\n", client_nonce);
	
	msg_HandShake.type = HAND04;
	//msg_HandShake.msg = obuf;
	memcpy(&(msg_HandShake.msg), &obuf, sizeof(obuf));
	
	_print_key("server reve: client_public", client_public);
		
	if (send(sFd, (char *)&msg_HandShake, sizeof(MSG_HandShake), 0) == ERROR) {
		shutdown(sFd,0);
		return;
	}
	printf ("server SEND HAND04\n");
	
	printf ("client ip is %s\n", ip);
	
	memcpy(&(keyNode.secret_key), &server_secret, sizeof(server_secret));
	memcpy(keyNode.ip, ip, sizeof(*ip));
	keyNode.req_times = 0;
	keyNode.traffic = 0;
	printf ("------");
	if (currentLength < SERVER_MAX_CONNECTIONS){
		//key[current++] = keyNode;
		memcpy(&(key[currentLength++]), &keyNode, sizeof(keyNode));
		printf ("key add successful...\n");
	}
	

/*	if (recv(sFd, (char *) client_msg, 20, 0) < 0) {
		printf("\t\t tcs_tcp_msg_recv error!\n");
		shutdown(sFd, 0);
		return;
	}
	printf("server get msg: %s\n",client_msg);


 	server_msg = "I am server";
	printf("server send: %s\n",server_msg);
	if (send(sFd, (char *)server_msg,20 ,0) == ERROR) {
		printf("send error\n");
		shutdown(sFd, 0);
		return;
	}
*/
}


